from fastapi import Depends, HTTPException, status, WebSocket
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from typing import Optional
import logging

from app.services.json_auth_service import JSONAuthService
from app.services.json_task_service import JSONTaskService
from app.services.crawl_service import MockCrawlService

logger = logging.getLogger(__name__)

# Security
security = HTTPBearer()

# Service instances
auth_service = JSONAuthService()

def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(security)
) -> dict:
    """获取当前用户"""
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    
    try:
        # 验证令牌
        payload = auth_service.verify_token(credentials.credentials, "access")
        if payload is None:
            raise credentials_exception
        
        user_id: str = payload.get("sub")
        if user_id is None:
            raise credentials_exception
        
        # 获取用户信息
        user = auth_service.get_user_by_id(user_id)
        if user is None:
            raise credentials_exception
        
        return user
        
    except Exception as e:
        logger.error(f"Authentication error: {e}")
        raise credentials_exception

def get_current_user_ws(
    websocket: WebSocket,
    token: str
) -> dict:
    """WebSocket认证 - 获取当前用户"""
    try:
        # 验证令牌
        payload = auth_service.verify_token(token, "access")
        if payload is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        
        user_id: str = payload.get("sub")
        if user_id is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        
        # 获取用户信息
        user = auth_service.get_user_by_id(user_id)
        if user is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        
        return user
        
    except Exception as e:
        logger.error(f"WebSocket authentication error: {e}")
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

def get_current_user_optional(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(HTTPBearer(auto_error=False))
) -> Optional[dict]:
    """获取当前用户（可选）"""
    if not credentials:
        return None
    
    try:
        return get_current_user(credentials)
    except HTTPException:
        return None

def require_admin(
    current_user: dict = Depends(get_current_user)
) -> dict:
    """要求管理员权限"""
    if current_user.get('role') != "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="需要管理员权限"
        )
    return current_user

def require_active_user(
    current_user: dict = Depends(get_current_user)
) -> dict:
    """要求活跃用户"""
    if not current_user.get('is_active', True):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="用户账户已被禁用"
        )
    return current_user

def require_permission(permission: str):
    """权限检查装饰器"""
    def permission_checker(user: dict = Depends(get_current_user)):
        # 简单的权限检查 - 可以根据需要扩展
        if user.get('role') == "admin":
            return user  # 管理员拥有所有权限
        
        # 这里可以添加更复杂的权限逻辑
        # 例如检查用户的权限列表等
        
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=f"需要权限: {permission}"
        )
    
    return permission_checker

def get_auth_service() -> JSONAuthService:
    """获取认证服务实例"""
    return auth_service

def get_crawl_service() -> MockCrawlService:
    """获取爬虫服务实例"""
    return MockCrawlService()

def get_task_service() -> JSONTaskService:
    """获取任务服务实例"""
    return JSONTaskService()

# 速率限制相关
class RateLimiter:
    """简单的速率限制器"""
    
    def __init__(self, max_requests: int = 100, window_seconds: int = 60):
        self.max_requests = max_requests
        self.window_seconds = window_seconds
        self.requests = {}
    
    def is_allowed(self, key: str) -> bool:
        """检查是否允许请求"""
        import time
        now = time.time()
        
        # 清理过期的记录
        self.requests = {
            k: v for k, v in self.requests.items() 
            if now - v['first_request'] < self.window_seconds
        }
        
        if key not in self.requests:
            self.requests[key] = {
                'count': 1,
                'first_request': now
            }
            return True
        
        if self.requests[key]['count'] >= self.max_requests:
            return False
        
        self.requests[key]['count'] += 1
        return True

# 全局速率限制器实例
rate_limiter = RateLimiter()

def check_rate_limit(
    request_key: str = None,
    current_user: Optional[dict] = Depends(get_current_user_optional)
):
    """检查速率限制"""
    # 使用用户ID或IP作为限制键
    if current_user:
        key = f"user:{current_user['id']}"
    else:
        key = request_key or "anonymous"
    
    if not rate_limiter.is_allowed(key):
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="请求过于频繁，请稍后再试"
        )
    
    return True
